package pc

import (
	. "chess_platform/internal/common"
	"chess_platform/models/h5"
	"chess_platform/models/pc"
	"chess_platform/modules"
	"fmt"
	"time"
)

//[pc]agent:代理管理
type AgentController struct {
	GrantController
}

func (b *AgentController) URLMapping() {
	//formal:代理列表
	b.Mapping("Unbind", b.Unbind)
	b.Mapping("ChangeAgentRelation", b.ChangeAgentRelation)

	b.Mapping("UpdateAgent", b.UpdateAgent)
	b.Mapping("UpdateBank", b.UpdateBank)
	b.Mapping("CancelAgent", b.CancelAgent)
	b.Mapping("AddDiamond", b.AddDiamond)
	b.Mapping("DecreaseDiamond", b.DecreaseDiamond)
	b.Mapping("ChangeStatus", b.ChangeStatus)
	b.Mapping("ChangeAgentNum", b.ChangeAgentNum)
	b.Mapping("UpdateInviteName", b.UpdateInviteName)
	b.Mapping("UpdateIsWithdraw", b.UpdateIsWithdraw)

	//informal:代理审核
	b.Mapping("MakeAgentFormal", b.MakeAgentFormal)
	b.Mapping("ManualReview", b.ManualReview)
	b.Mapping("ListUnofficialH5User", b.ListUnofficialH5User)

	//area:区域查看
	b.Mapping("ListAreaGroup", b.ListAreaGroup)
}

// @Title 解除推广员与代理员关系
// @Description 解除推广员与代理员关系
// @Param   uid            body   int     true       "要审核的用户id"
// @Success 0 {string} 状态码
// @router /formal/unbind [post]
func (b *AgentController) Unbind() {
	type Params struct {
		Uid int64 `json:"uid" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	//审核之前先判断下二级代理绑定了手机了没有
	field := []string{"status"}
	u, err := h5.SpecifyUserInfoById(p.Uid, field)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	if u.Status == FirstTopUpSuccess {
		b.ResponseFail("正式代理不能解除关系,请选择注销")
		return
	}

	user := map[string]interface{}{
		"status": VerifyNotPass,
	}
	//更新被审核的代理状态
	_, err = h5.UpdateUser(user, p.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}

	//如果审核失败，就还原一个开通代理的名额
	//更新自己的代理数加1
	_, err = h5.UpdateUserAgentNum(1, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 改变代理所属的推广员(代理与推广员的关系)
// @Description 改变代理所属的推广员(代理与推广员的关系)
// @Param   uid            body   int     true       "要改变的代理的id"
// @Param   pid            body   int     true       "新的所属代理的id"
// @Success 0 {string} 状态码
// @router /formal/change-agent-relation [post]
func (b *AgentController) ChangeAgentRelation() {
	type Params struct {
		Uid int64 `json:"uid" valid:"Required"`
		Pid int64 `json:"pid" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	/*
		1. 判断新归属代理名额是否足够，如果足够进行第二步
		2. 要还原旧归属一个代理名额，减少新归属一个代理名额
		3. 修改归属
	*/

	field := []string{"status", "pid", "level"}
	uu, err := h5.SpecifyUserInfoById(p.Uid, field)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	if uu.Level != Level2 {
		b.ResponseFail("只能修改二级代理的所属推广员")
		return
	}
	if uu.Status != FirstTopUpSuccess {
		b.ResponseFail("非正式代理更改所属推广员,请选择解除关系")
		return
	}

	field = []string{"status", "group_id", "agent_num"}
	pp, err := h5.SpecifyUserInfoById(p.Pid, field)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	if pp.AgentNum <= 0 {
		b.ResponseFail("新的所属扩广员代理名额不足")
		return
	}

	_, err = h5.UpdateAgentRelation(p.Uid, uu.Pid, p.Pid, pp.GroupId)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 更新代理信息(手机号,密码,大区归属)
// @Description 更新代理信息(手机号,密码,大区归属)
// @Param   uid             body    int     true      "代理的id"
// @Param   phone           body    string  false     "手机号"
// @Param   password        body    string  false     "密码,密码,传空表示不修改密码"
// @Param   group_id        body    int     true      "代理归属的大区"
// @Param   agent_num       body    int     true      "一级代理招募二级代理名额数"
// @Success 0 {string} 状态码
// @router /formal/update-agent [post]
func (b *AgentController) UpdateAgent() {
	type Params struct {
		Uid      int64  `json:"uid" valid:"Required"`
		Phone    string `json:"phone"`
		Password string `json:"password"`
		GroupId  int64  `json:"group_id"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if p.Phone != "" {
		b.Valid.Phone(p.Phone, "phone").Message("请输入正确的手机号")
	}
	if !b.ValidParams(&p) {
		return
	}
	if p.Phone != "" {
		uid, err := h5.IsUserExistByPhone(p.Phone)
		if err != nil {
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
		if uid != 0 && uid != p.Uid {
			b.Res.Code = ErrAlreadyExist
			b.Res.Msg = MsgErrPhoneAlreadyExist
			b.Response()
			return
		}
	}

	data := map[string]interface{}{
		"phone": p.Phone,
	}
	if p.Password != "" {
		data["password"] = Md5sum(p.Password)
	}
	_, err := h5.UpdateUser(data, p.Uid)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	field := []string{"group_id", "level"}
	u, err := h5.SpecifyUserInfoById(p.Uid, field)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	msg := fmt.Sprintf("更新代理用户(ID%v)的信息", p.Uid)
	//一级代理才可以修改所属大区,二级代理是随着一级代理改变而改变的
	if u != nil && u.GroupId != p.GroupId && u.Level == Level1 {
		//要修改group_id
		_, err = h5.UpdateUserGroupId(p.GroupId, p.Uid)
		if err != nil {
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
		msg = fmt.Sprintf("更新代理用户(ID%v)的信息,旧的大区为:%v,新的大区为:%v", p.Uid, u.GroupId, p.GroupId)
	}

	b.ResponseSuccess()
	b.NewLog(LogAgent, OpUpdate, msg, data)
}

// @Title 更新银行卡信息(同时也是新增)
// @Description 更新银行卡信息(同时也是新增)
// @Param   agent_id        body    int     true      "代理的id"
// @Param   name            body    string  true      "户名"
// @Param   bank_name      	body    string  true      "开户行名字(工商银行，中国银行)"
// @Param   province        body    string  true      "开户行所在省"
// @Param   city            body    string  true      "开户行所在市"
// @Param   card_num        body    string  true      "银行帐号"
// @Param   branch          body    string  true      "银行支行"
// @Success 0 {string} 状态码
// @Failure 399
// @router /formal/update-bank [post]
func (b *AgentController) UpdateBank() {
	type Params struct {
		AgentBank
		AgentId int64 `json:"agent_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.MinSize(p.Name, 2, "Name").Message("名字长度2-16")
	b.Valid.MaxSize(p.Name, 16, "Name").Message("名字长度2-16")
	b.Valid.MatchChinese(p.Name, "name").Message("")
	b.Valid.Required(p.BankName, "bank_name").Message("请输入开户行名")
	b.Valid.Required(p.Province, "province").Message("请输入开户行所在省")
	b.Valid.Required(p.City, "city").Message("请输入开户行所在市")
	b.Valid.Required(p.CardNum, "card_num").Message("请输入银行帐号")
	b.Valid.Required(p.Branch, "branch").Message("请输入银行支行")
	if !b.VerifyParamsError() {
		return
	}
	ab, _, err := h5.AgentBankById(p.AgentId)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	data := map[string]interface{}{
		"uid":         p.AgentId,
		"name":        p.Name,
		"bank_name":   p.BankName,
		"province":    p.Province,
		"city":        p.City,
		"card_num":    p.CardNum,
		"branch":      p.Branch,
		"create_time": time.Now().Unix(),
	}
	if ab == nil { //doesn't exist, we should new one
		_, err := h5.NewAgentBank(data)
		if err != nil {
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}

	} else { //exist update bank info
		_, err := h5.UpdateAgentBank(data, b.Uid)
		if err != nil {
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
	}
	b.ResponseSuccess()
}

// @Title 注销代理帐号
// @Description 注销代理帐号
// @Param   uid               body    int     true      "代理uid"
// @Success 0 {string} 状态码
// @router /formal/cancel-agent [post]
func (b *AgentController) CancelAgent() {
	type Params struct {
		Uid int64 `json:"uid" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	field := []string{"open_id", "phone"}
	u, err := h5.SpecifyUserInfoById(p.Uid, field)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if u == nil {
		b.ResponseFail("此代理不存在")
		return
	}

	//注销帐号,是否冻结,1-是，0-否,2-注销
	user := map[string]interface{}{
		"frozen":  2,
		"open_id": fmt.Sprintf("%v--%v", u.OpenId, p.Uid),
		"phone":   fmt.Sprintf("%v--%v", u.Phone, p.Uid),
	}
	_, err = h5.UpdateUser(user, p.Uid)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	msg := fmt.Sprintf("注销代理(uid:%v)", p.Uid)
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 增加代理钻石
// @Description 增加代理钻石
// @Param   uid               body    int     true      "代理uid"
// @Param   diamond_num       body    string  true      "钻石数量"
// @Success 0 {string} 状态码
// @router /formal/add-diamond [post]
func (b *AgentController) AddDiamond() {
	type Params struct {
		Uid        int64 `json:"uid" valid:"Required"`
		DiamondNum int64 `json:"diamond_num"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Min(p.DiamondNum, 1, "diamond_num").Message("请输入大于1钻石数")
	if !b.ValidParams(&p) {
		return
	}
	diamond := MathAbs(p.DiamondNum)
	o := NewDBOrm(DBChessCenter)
	o.Begin()
	defer o.Rollback()
	err := modules.ChangeH5AgentCard(p.Uid, diamond, b.Uid, o)
	if err != nil {
		o.Rollback()
		LogPc.Error(b.SystemError(err.Error()))
		return
	}
	o.Commit()
	b.ResponseSuccess()
	msg := fmt.Sprintf("增加代理(uid:%v)钻石(%v)", p.Uid, diamond)
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 减少玩家钻石
// @Description 减少玩家钻石
// @Param   uid               body    int     true      "代理uid"
// @Param   diamond_num       body    string  true      "钻石数量,传正值"
// @Success 0 {string} 状态码
// @router /formal/decrease-diamond [post]
func (b *AgentController) DecreaseDiamond() {
	type Params struct {
		Uid        int64 `json:"uid" valid:"Required"`
		DiamondNum int64 `json:"diamond_num"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Min(p.DiamondNum, 1, "diamond_num").Message("请输入大于0钻石数")
	if !b.ValidParams(&p) {
		return
	}
	diamond := MathAbs(p.DiamondNum)

	o := NewDBOrm(DBChessCenter)
	o.Begin()
	defer o.Rollback()
	err := modules.ChangeH5AgentCard(p.Uid, -diamond, b.Uid, o)
	if err != nil {
		o.Rollback()
		LogPc.Error(b.SystemError(err.Error()))
		return
	}
	o.Commit()
	b.ResponseSuccess()
	msg := fmt.Sprintf("减少代理(uid:%v)钻石(%v)", p.Uid, diamond)
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 冻结解冻代理用户
// @Description 冻结解冻代理用户
// @Param   id             body    int     true      "代理的id"
// @Param   frozen  	   body    int     true      "是否冻结,1-冻结，0-解冻"
// @Param   frozen_reason  body    int     false     "冻结理由"
// @Success 0 {string} 状态码
// @router /formal/change-status [post]
func (b *AgentController) ChangeStatus() {
	type Params struct {
		Id           int64  `json:"id" valid:"Required"`
		Frozen       int64  `json:"frozen" valid:"Range(0,1)"`
		FrozenReason string `json:"frozen_reason"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	user := map[string]interface{}{
		"frozen": p.Frozen,
	}

	msg := fmt.Sprintf("解冻代理用户(ID%v)", p.Id)
	if p.Frozen == 1 {
		user["frozen_reason"] = p.FrozenReason
		msg = fmt.Sprintf("冻结代理用户(ID%v)冻结理由:%v", p.Id, p.FrozenReason)
	}
	_, err := h5.UpdateUser(user, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 填写此代理的推荐人
// @Description 填写此代理的推荐人
// @Param   id             body    int     true      "代理的id"
// @Param   invite_name    body    int     false     "此代理的推荐人"
// @Success 0 {string} 状态码
// @router /formal/update-invite-name [post]
func (b *AgentController) UpdateInviteName() {
	type Params struct {
		Id         int64  `json:"id" valid:"Required"`
		InviteName string `json:"invite_name"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	user := map[string]interface{}{
		"invite_name": p.InviteName,
	}

	_, err := h5.UpdateUser(user, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	msg := fmt.Sprintf("更新代理用户(ID%v)的推荐人为:%v", p.Id, p.InviteName)
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 开启关闭推广员提现
// @Description 开启关闭推广员提现
// @Param   id             body    int     true      "代理的id"
// @Param   is_withdraw    body    int     true      "是否有权限提现，1-有,0-没有"
// @Success 0 {string} 状态码
// @router /formal/update-is-withdraw [post]
func (b *AgentController) UpdateIsWithdraw() {
	type Params struct {
		Id         int64 `json:"id" valid:"Required"`
		IsWithdraw int64 `json:"is_withdraw" valid:"Range(0,1)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	user := map[string]interface{}{
		"is_withdraw": p.IsWithdraw,
	}

	_, err := h5.UpdateUser(user, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	msg := fmt.Sprintf("更新代理用户(ID%v)的是否具有提现功能(1-可以,0-不能):%v", p.Id, p.IsWithdraw)
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 设置代理的名额
// @Description 设置代理的名额
// @Param   id          body    int     true      "用户id"
// @Param   agent_num   body    int     true      "代理的名额(正数为增加,负数为减少)"
// @Success 0 {string} 状态码
// @router /formal/change-agent-num [post]
func (b *AgentController) ChangeAgentNum() {
	type Params struct {
		Id       int64 `json:"id" valid:"Required"`
		AgentNum int64 `json:"agent_num"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	_, err := h5.UpdateUserAgentNum(p.AgentNum, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	msg := fmt.Sprintf("改变推广员(ID%v)招募代理(增加或减少)名额:%v个", p.Id, p.AgentNum)
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 人工审核一级代理
// @Description 人工审核一级代理
// @Param   status         body   int     true       "4-通过，3-不通过"
// @Param   uid            body   int     true       "要审核的用户id"
// @Param   group_id       body   int     true       "所属的大区"
// @Success 0 {string} 状态码
// @router /informal/manual-review [post]
func (b *AgentController) ManualReview() {
	type Params struct {
		Status  int64 `json:"status" valid:"Range(3,4)"`
		Uid     int64 `json:"uid" valid:"Required"`
		GroupId int64 `json:"group_id"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	//审核之前先判断下代理绑定了手机了没有
	field := []string{"status"}
	u, err := h5.SpecifyUserInfoById(p.Uid, field)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))

		return
	}
	if u.Level == Level2 {
		b.ResponseFail("只能审核一级代理")
		return
	}
	if u.Status < BindPhoneSuccess {
		b.ResponseFail("代理还未绑定手机,请等待")
		return
	}
	user := map[string]interface{}{
		"status":   p.Status,
		"group_id": p.GroupId,
	}
	_, err = h5.UpdateUser(user, p.Uid)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	msg := fmt.Sprintf("审核代理用户(ID%v)为拒绝", p.Uid)
	if p.Status == VerifyPass {
		msg = fmt.Sprintf("审核代理用户(ID%v)为通过,分配的大区ID:%v", p.Uid, p.GroupId)
	}
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 修改代理的状态为正式代理(直接跳过第一次充值)
// @Description 修改代理的状态为正式代理(直接跳过第一次充值)
// @Param   uid            body   int     true       "要审核的用户id"
// @Success 0 {string} 状态码
// @router /informal/make-agent-formal [post]
func (b *AgentController) MakeAgentFormal() {
	type Params struct {
		Uid int64 `json:"uid" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	err := modules.InitAgent(p.Uid, 0)
	if err == MsgAgentAlreadyFormal {
		b.ResponseFail(MsgAgentAlreadyFormal.Error())
		return
	}
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	msg := fmt.Sprintf("直接修改代理用户(ID%v)为正式代理,跳过了第一次充值", p.Uid)
	b.NewLog(LogAgent, OpUpdate, msg, map[string]interface{}{})
}

// @Title 获取当前管理员管理的代理用户列表(非正式的一级代理)
// @Description 获取当前管理员管理的代理用户列表(非正式的一级代理)
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   uid          body   int     false      "代理id"
// @Param   phone        body   string  false      "手机号"
// @Success 0 {object} []common.H5User 代理用户列表
// @router /informal/list-unofficial-h5user [post]
func (b *AgentController) ListUnofficialH5User() {
	type Params struct {
		ListParams
		Uid   int64  `json:"uid"`
		Phone string `json:"phone"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	user, err := pc.ListAllExpireH5User()
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	for _, v := range user {
		h5.HandleAgentStatus(v.CreateTime, v.Uid, 0, false)
	}

	users, count, err := pc.ListUnofficialH5User(p.ListParams, p.Phone, p.Uid)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = users
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 获取大区列表
// @Description 获取大区列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []common.Group 代理用户列表
// @router /informal/list-group [post]
func (b *AgentController) ListGroup() {
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data, count, err := pc.ListGroup(p)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = data
	b.Res.Count = count
	b.ResponseSuccess()
}

//--------------------------------------区域查看-推广员-代理--------------------------------------------//
// @Title 获取大区列表
// @Description 获取大区列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []common.Group 代理用户列表
// @router /area/list-group [post]
func (b *AgentController) ListAreaGroup() {
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data, count, err := pc.ListAreaGroup(p)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = data
	b.Res.Count = count
	b.ResponseSuccess()
}
